/*
 * Copyright (c) 2011 Joe Kopena <tjkopena@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.rocketshipgames.as3 {

  import flash.display.MovieClip;
  import flash.display.Bitmap;
  import flash.events.IOErrorEvent;
  import flash.events.Event;
  import flash.display.DisplayObject;
  import flash.utils.getDefinitionByName;

  import flash.utils.getTimer;

  import flash.text.TextField;
  import flash.text.TextFormat;
  import flash.geom.Point;
  import flash.display.Shape;

  public class Preloader extends MovieClip {

    [Embed(source = '/assets/rockethaxe-x100.png')]
      private var Logo:Class;

    private var _minDelay:Number;
    private var _wrapperClassname:String;

    private var _startTimestamp:Number;
    private var _time:Number;

    private var _borderBar:Shape;
    private var _progressBar:Shape;
    private var _bytesDisplay:TextField;
    private var _logo:Bitmap;

    private var _ready:Boolean;

    private static const BAR_WIDTH:Number = 400;
    private static const BAR_HEIGHT:Number = 8;
    private static const MARGIN:Number = 2;

    public function Preloader(wrapperClassname:String="Wrapper",
			      minDelay:Number=0,
			      logoClass:Class=null)
    {
      stop();
      _ready = false;

      if (logoClass == null)
	logoClass = Logo;

      _wrapperClassname = wrapperClassname;
      _minDelay = minDelay;

      _borderBar = new Shape();
      _borderBar.graphics.lineStyle(1,0xff000000);
      _borderBar.graphics.drawRect(-MARGIN, -MARGIN,
				   BAR_WIDTH + (MARGIN*2),
				   BAR_HEIGHT + (MARGIN*2));

      _progressBar = new Shape();
      _progressBar.graphics.beginFill(0xff000000);
      _progressBar.graphics.drawRect(0, 0, BAR_WIDTH, BAR_HEIGHT);
      _progressBar.graphics.endFill();

      _bytesDisplay = new TextField();
      var format:TextFormat = new TextFormat(null,10);
      _bytesDisplay.defaultTextFormat = format;
      _bytesDisplay.autoSize = 'left';
      _bytesDisplay.text = "Loading...";

      _logo = new logoClass();

      addChild(_logo);
      addChild(_bytesDisplay);
      addChild(_borderBar);
      addChild(_progressBar);

      addEventListener(Event.ENTER_FRAME, onEnterFrame);
      addEventListener(Event.ADDED_TO_STAGE, onStage);

      // end function Preloader
    }

    private function onStage(e:Event=null):void
    {
      _startTimestamp = getTimer();

      _progressBar.x = _borderBar.x = (stage.stageWidth - _progressBar.width)/2;
      _progressBar.y = _borderBar.y = (stage.stageHeight -
				       (_borderBar.height+1));

      _bytesDisplay.x = _borderBar.x - (_bytesDisplay.width + MARGIN*2);
      _bytesDisplay.y = _borderBar.y + (BAR_HEIGHT-_bytesDisplay.height)/2;

      _logo.x = stage.stageWidth - (_logo.bitmapData.width + MARGIN);
      _logo.y = stage.stageHeight - (_logo.bitmapData.height + MARGIN);

      // end function onStage
    }

    private function onEnterFrame(e:Event):void
    {
      var currTime:Number = getTimer();

      _time = currTime - _startTimestamp;

      if (_ready) {
	checkAdvance();
      } else {
	var lk:Number = root.loaderInfo.bytesLoaded/1024;
	var lt:Number = root.loaderInfo.bytesTotal/1024;
	_bytesDisplay.text = "[" + lk.toFixed(2) + "k/" + lt.toFixed(2)+ "k]";
	_bytesDisplay.x = _borderBar.x - (_bytesDisplay.width + MARGIN*2);

	_progressBar.scaleX = root.loaderInfo.bytesLoaded /
	  root.loaderInfo.bytesTotal;

	if (root.loaderInfo.bytesLoaded == root.loaderInfo.bytesTotal) {
	  // removeChild(_borderBar);
	  // removeChild(_progressBar);
	  _bytesDisplay.text = "[ready]";
	  _bytesDisplay.x = _borderBar.x - (_bytesDisplay.width + MARGIN*2);
	  checkAdvance(); // In case _minDelay is 0
	}
      }
      // end onEnterFrame
    }

    private function checkAdvance():void
    {
      _ready = true;
      if (_time > _minDelay) {
	nextFrame();

	var mainClass:Class = Class(getDefinitionByName(_wrapperClassname));
	if (mainClass) {
	  var app:Object = new mainClass();
	  stage.addChild(app as DisplayObject);
	  removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	  stage.removeChild(this);
	  trace("Out of here");
	} else {
	  _bytesDisplay.text = "ERROR: Could not find wrapper class '" +
	    _wrapperClassname + "'";
	}
      }
      // end function checkAdvance
    }

    // end class Preloader
  }

  // end package
}
